﻿using System;
using System.Net;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Text.RegularExpressions;
using PocketGPW.PocketGPWDataSetTableAdapters;

namespace PocketGPW
{
    public partial class StockEditor : Form
    {
        private class Stock
        {
            public string Id { get; set; }
            public string Name { get; set; }
        }

        private static readonly Regex _rxMembers = new Regex(@"<a\s*href\s*=\s*(?:\""\S*(?<id>[A-Z]{2}[A-Z0-9]{9}[0-9])\S*\"")>(?<name>.*?)</a></td>\s*</tr>", RegexOptions.IgnoreCase | RegexOptions.Multiline);

        private PocketGPWDataSet _ds;
        private StocksTableAdapter _taStocks;
        private Thread _thread;
        private Dictionary<string, List<Stock>> _stocks;
        private string _source;
        private string _source_type;

        public StockEditor(PocketGPWDataSet ds, StocksTableAdapter taStocks)
        {
            InitializeComponent();

            Icon = Properties.Resources.Icon;

            _ds = ds;
            _taStocks = taStocks;

            _stocks = new Dictionary<string, List<Stock>>();
            _source_type = "S";

        }

        private void _miAdd_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem lvi in _lv.Items)
            {
                if (!lvi.Checked)
                    continue;

                lvi.Checked = false;

                // sprawdzamy czy już czasem taki nie istnieje
                if (_ds.Stocks.Where(dr => dr["StockId"].ToString() == lvi.Tag.ToString()).Count() > 0)
                    continue;

                DataRow newRow = _ds.Stocks.NewStocksRow();
                newRow["StockId"] = lvi.Tag;
                newRow["Name"] = lvi.Text;
                newRow["Type"] = _source_type;
                _ds.Stocks.Rows.Add(newRow);
            }

            // update
            _taStocks.Update(_ds.Stocks);

            Hide();
        }

        private void _miCancel_Click(object sender, EventArgs e)
        {
            Hide();
        }

        private void DownloadStocks()
        {
            HttpWebRequest request = null;
            HttpWebResponse response = null;
            string responseString = String.Empty ;
            string url = String.Format("http://www.gpw.pl/ajaxindex.php?action=GPWCompanySearch&start=listForLetter&letter={0}&listTemplateName=GPWCompanySearch%2FajaxList_PL", _source);

            if (_source == "0-9")
            {
                _source = "1";
                url = String.Format("http://www.gpw.pl/ajaxindex.php?action=GPWCompanySearch&start=listForLetter&letter={0}&listTemplateName=GPWCompanySearch%2FajaxList_PL", _source);                                
            }

            if (_source.Length > 1)
                url = String.Format("http://www.gpw.pl/ajaxindex.php?action=GPWCompanySearch&start=listForIndex&index={0}&listTemplateName=GPWCompanySearch/ajaxList_PL", _source);
                
            try
            {
                request = HTTPHelper.CreateRequest(url);
                if (request == null)
                    return;

                response = (HttpWebResponse)request.GetResponse();
                responseString = HTTPHelper.ReadResponse(response).Replace("<![CDATA[", string.Empty).Replace("]]>", string.Empty).Replace("&nbsp;", string.Empty);
                response.Close();
            }
            catch
            {
                BeginInvoke(new Action(DownloadError));
            }
            finally
            {
                request.Abort();
                response = null;
                request = null;
            }

            if (responseString != String.Empty)
            {
                List<Stock> s = new List<Stock>();

                MatchCollection ma = _rxMembers.Matches(responseString);
                foreach (Match m in ma)
                    if (m.Groups.Count > 0)
                        s.Add(new Stock() { Id = m.Groups["id"].Value.ToString(), Name = m.Groups["name"].Value.ToString() });

                _stocks.Add(_source, s);

                BeginInvoke(new Action(DownloadSuccess));
            }
        }

        private void DownloadError()
        {
            MessageBox.Show("Wystąpił błąd. Proszę spróbować ponownie.", "Pocket GPW", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);

            _lbl.Visible = false;
            _p.Visible = true;
            _miAdd.Enabled = true;           
        }

        private void DownloadSuccess()
        {
            ReloadListView(_source);
            
            _lbl.Visible = false;
            _p.Visible = true;
            _miAdd.Enabled = true;
        }

        private void ReloadListView(string key)
        {
            _lv.Items.Clear();

            foreach (Stock s in _stocks[key])
            {
                if (_ds.Stocks.Rows.Contains(s.Id))
                    continue;

                if (_tbKeyword.Text.Length > 0 && !s.Name.ToLower().Contains(_tbKeyword.Text.ToLower()))
                    continue;

                ListViewItem lvi = new ListViewItem(s.Name);
                lvi.Tag = s.Id;

                _lv.Items.Add(lvi);
            }
        }

        private void StockEditor_Activated(object sender, EventArgs e)
        {
            // pierwsze odpalenie - nie robimy nic
            if (_stocks == null)
                return;
        }

        private void _tbKeyword_TextChanged(object sender, EventArgs e)
        {
            ReloadListView(_source);
        }

        private void _cb_SelectedIndexChanged(object sender, EventArgs e)
        {
            _source = ((ComboBox)sender).Text;
            if (!_stocks.ContainsKey(_source))
            {
                _lbl.Visible = true;
                _p.Visible = false;

                _thread = new Thread(new ThreadStart(DownloadStocks));
                _thread.IsBackground = true;
                _thread.Start();
            }
            else DownloadSuccess();

        }        
    }
}